package com.hkts.naturalgas.index.service.serviceimpl;

import com.baomidou.mybatisplus.core.toolkit.StringUtils;
import com.hkts.naturalgas.index.entity.ParamVo;
import com.hkts.naturalgas.index.mapper.IndexMapper;
import com.hkts.naturalgas.utils.DateUtils;
import com.hkts.naturalgas.utils.Result;
import com.hkts.naturalgas.utils.ResultUtil;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.time.LocalDate;
import java.time.format.DateTimeFormatter;
import java.time.temporal.ChronoUnit;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.stream.Collectors;
import java.util.stream.Stream;

@Service
@Transactional
@Slf4j
public class IndexServiceImpl {


    @Autowired
    private IndexMapper indexMapper;
    public Result<Object> countIndex(ParamVo param){
        Map<String, Object> map=new HashMap<>();
        param.setSelectType(0);
        if(StringUtils.isBlank(param.getDepartId())){

            getDateTime(param);
            int countHontLog=indexMapper.countHontLog(param);
            int countInstanceinfo=indexMapper.countInstanceinfo(param);
            param.setSelectType(3);
            getDateTime(param);
            int countInstanceinfoMouth=indexMapper.countInstanceinfo(param);
            map.put("hontLog",countHontLog);
            map.put("countInstanceinfo",countInstanceinfo);
            map.put("countInstanceinfoMouth",countInstanceinfoMouth);

        }else {
            int countInstanceinfo=indexMapper.countInstanceinfo(param);
            param.setSelectType(3);
            getDateTime(param);
            int countInstanceinfoMouth=indexMapper.countInstanceinfo(param);
            int timeOut=indexMapper.countTimeOut(param);
            map.put("countInstanceinfo",countInstanceinfo);
            map.put("countInstanceinfoMouth",countInstanceinfoMouth);
            map.put("timeOut",timeOut);
        }
        return ResultUtil.data(map);
    }
    public Result<Object> countIndexHead(ParamVo param){
        getDateTime(param);
        Map<String, Object> map=new HashMap<>();
        //登录人数
        /*ParamVo paramToday = new ParamVo();
        paramToday.setSelectType(0);
        paramToday.setDepartId(param.getDepartId());
        getDateTime(paramToday);*/
        int countHontLog=indexMapper.countHontLog(param);
        int countInstanceinfo=indexMapper.countInstanceinfo(param);
        int sumInstanceinfoTime=indexMapper.sumInstanceinfoTime(param);
//        LocalDate currentDate= DateUtils.parseLocalDateTime(param.getBeginDate(),DateUtils.DATETIME_FORMATTER).toLocalDate();
//        LocalDate endDate= DateUtils.parseLocalDateTime(param.getBeginDate(),DateUtils.DATETIME_FORMATTER).toLocalDate();
//        if(endDate.isAfter(LocalDate.now())){
//            endDate=LocalDate.now();
//        }
//        long intervalTime=DateUtils.intervalHours(currentDate.atStartOfDay(),endDate.atStartOfDay());
        long avgInstanceinfoTime;
        if(countInstanceinfo>0){
             avgInstanceinfoTime= sumInstanceinfoTime/countInstanceinfo;
        }else{
             avgInstanceinfoTime=sumInstanceinfoTime;
        }
        int timeOut=indexMapper.countTimeOut(param);
        map.put("countHontLog",countHontLog);
        map.put("countInstanceinfo",countInstanceinfo);
        map.put("avgInstanceinfoTime",avgInstanceinfoTime);
        map.put("timeOut",timeOut);
        return ResultUtil.data(map);
    }
    public void getDateTime(ParamVo param){

        switch(param.getSelectType()){
            case ParamVo.day: {
                param.setBeginDate(DateUtils.getCurrentDate() + " 00:00:00");
                param.setEndDate(DateUtils.getCurrentDate() + " 23:59:59");
                break;
            }
            case ParamVo.yesterday:{
                param.setBeginDate(DateUtils.getFrontDate() + " 00:00:00");
                param.setEndDate(DateUtils.getFrontDate() + " 23:59:59");
                break;
            }
            case ParamVo.week: {
                param.setBeginDate( DateUtils.getCurrentWeekFirstDate().format(DateTimeFormatter.ofPattern(DateUtils.DATE_FORMATTER))+ " 00:00:00");
                param.setEndDate(DateUtils.getCurrentWeekLastDate().format(DateTimeFormatter.ofPattern(DateUtils.DATE_FORMATTER))+ " 23:59:59");
                break;
            }
            case ParamVo.month: {
                param.setBeginDate( DateUtils.getCurrentMonthFirstDate().format(DateTimeFormatter.ofPattern(DateUtils.DATE_FORMATTER))+ " 00:00:00");
                param.setEndDate( DateUtils.getCurrentMonthLastDate().format(DateTimeFormatter.ofPattern(DateUtils.DATE_FORMATTER))+ " 23:59:59");
                break;
            }
            default: {
                param.setBeginDate(param.getBeginDate()+ " 00:00:00");
                param.setEndDate(param.getEndDate()+ " 23:59:59");
                break;
            }
        }
    }
    public  List<Map<String, Object>> getHontLog(ParamVo param ){
        List<Map<String, Object>>  result;
        if(StringUtils.isBlank(param.getDepartId())){
              result= indexMapper.totalHontLogOnDePart(param.getBeginDate(),param.getEndDate());
        }else {

            String dateType="";
            if(ParamVo.day==param.getSelectType()||ParamVo.yesterday==param.getSelectType()){
                dateType="%H:00:00";
            }else {
                dateType="%Y-%m-%d";

            }
            List<Map<String, Object>>  totalHontLog= indexMapper.totalHontLog(dateType,param.getBeginDate(),param.getEndDate(),param.getDepartId());
            result=  getDateTimeLine(totalHontLog,param);
        }
//        List<Map<String, Object>> totalHontLogOnDePart= indexMapper.totalHontLogOnDePart(param.getBeginDate(),param.getEndDate());
//        data.put("data",totalHontLogOnDePart);
    return result;
    }
    public List<Map<String, Object>> getDateTimeLine( List<Map<String, Object>> items,ParamVo param){
        List<Map<String, Object>> data=new ArrayList<>();
        switch(param.getSelectType()){
            case ParamVo.day: {
              String date=  DateUtils.getCurrentDate();

                for (int i = 0; i <24 ; i++) {
                    String flag=i+":00:00";
                    if(i<10){
                        flag="0"+flag;
                    }
                    Map<String, Object> map=new HashMap<>();
                    String time=flag;
                    if(items.size()>0){
                        List<Map<String, Object>> list=   items.stream().filter(t->time.equals(t.get("time"))).collect(Collectors.toList());
                        if(list.size()>0){
                            data.addAll(list);
                            continue;
                        }
                    }
                    map.put("time",time);
                    map.put("count",0);
                    data.add(map);
                }
                break;
            }
            case ParamVo.yesterday: {
                String date=  DateUtils.getCurrentDate();

                for (int i = 0; i <24 ; i++) {
                    String flag=i+":00:00";
                    if(i<10){
                        flag="0"+flag;
                    }
                    Map<String, Object> map=new HashMap<>();
                    String time=flag;
                    if(items.size()>0){
                        List<Map<String, Object>> list=   items.stream().filter(t->time.equals(t.get("time"))).collect(Collectors.toList());
                        if(list.size()>0){
                            data.addAll(list);
                            continue;
                        }
                    }
                    map.put("time",time);
                    map.put("count",0);
                    data.add(map);
                }
                break;
            }
            default: {
                LocalDate start = DateUtils.parseLocalDateTime(param.getBeginDate(),DateUtils.DATETIME_FORMATTER).toLocalDate();
                LocalDate end = DateUtils.parseLocalDateTime(param.getEndDate(),DateUtils.DATETIME_FORMATTER).toLocalDate();
                List<LocalDate> dates = Stream.iterate(start, date -> date.plusDays(1))
                        .limit(ChronoUnit.DAYS.between(start, end)+1)
                        .collect(Collectors.toList());
                for(LocalDate item: dates){
                    Map<String, Object> map=new HashMap<>();
                    String time=DateUtils.formatLocalDate(item);
                    if(items.size()>0){
                        List<Map<String, Object>> list=   items.stream().filter(t->time.equals(t.get("time"))).collect(Collectors.toList());
                        if(list.size()>0){
                            data.addAll(list);
                            continue;
                        }
                    }
                    map.put("time",time);
                    map.put("count",0);
                    data.add(map);
                }
                break;
            }
        }
        return data;

    }
    public  List<Map<String, Object>> getInstanceinfoCount(ParamVo param ){
        List<Map<String, Object>> result;
        if(StringUtils.isBlank(param.getDepartId())){

            result= indexMapper.totalInstanceinfoOnDePart(param.getBeginDate(),param.getEndDate());
        }else {

            String dateType="";
            if(ParamVo.day==param.getSelectType()||ParamVo.yesterday==param.getSelectType()){
                dateType="%H:00:00";
            }else {
                dateType="%Y-%m-%d";

            }
            List<Map<String, Object>> totalInstanceinfoCountDay= indexMapper.totalInstanceinfoCount(dateType,param.getBeginDate(),param.getEndDate(),param.getDepartId());
           result=  getDateTimeLine(totalInstanceinfoCountDay,param);
        }
        return result;
    }
    public Result<Object> countIndexCentre(ParamVo param ){

        getDateTime(param);
        Map<String,Object> map=new HashMap<>();
        List<Map<String, Object>>  hongLogCount= getHontLog(param );
        List<String> categories = new ArrayList<>();
        List<Integer> data = new ArrayList<>();
        hongLogCount.forEach(map1 -> {
            categories.add(map1.get("time").toString());
            if(Integer.parseInt(map1.get("count").toString())!=0){

                data.add(Integer.parseInt(map1.get("count").toString()));
            }
        });
        Map<String,Object> series = new HashMap<>();
        series.put("name","次数");
        series.put("data",data);
        List<Object> seriesList = new ArrayList<>();
        seriesList.add(series);
        Map<String,Object> hongLogCountMap = new HashMap<>();
        hongLogCountMap.put("categories",categories);
        hongLogCountMap.put("series",seriesList);
        map.put("hongLogCount",hongLogCountMap);
        List<Map<String, Object>> instanceinfoCount= getInstanceinfoCount(param );
        List<String> instanceCategories = new ArrayList<>();
        List<Integer> instanceData = new ArrayList<>();
        instanceinfoCount.forEach(map1 -> {
            instanceCategories.add(map1.get("time").toString());
            if(Integer.parseInt(map1.get("count").toString())!=0){

             instanceData.add(Integer.parseInt(map1.get("count").toString()));
            }
        });
        Map<String,Object> instanceSeries = new HashMap<>();
        instanceSeries.put("name","次数");
        instanceSeries.put("data",instanceData);
        List<Object> instanceSeriesList = new ArrayList<>();
        instanceSeriesList.add(instanceSeries);
        Map<String,Object> instanceSCountMap = new HashMap<>();
        instanceSCountMap.put("categories",instanceCategories);
        instanceSCountMap.put("series",instanceSeriesList);
        map.put("instanceinfoCount",instanceSCountMap);
        return ResultUtil.data(map);
    }
    public Result<Object> countIndexBottomAvg(ParamVo param ){
        getDateTime(param);
        List<Map<String, Object>>  countIndexBottomAvg;
        if(StringUtils.isBlank(param.getDepartId())){
             countIndexBottomAvg= indexMapper.countIndexBottomAvg(param.getBeginDate(),param.getEndDate());

        }else {
            countIndexBottomAvg= indexMapper.countIndexBottomAvgOnUser(param.getBeginDate(),param.getEndDate(),param.getDepartId());

        }
        List<Object> instanceCategories = new ArrayList<>();
        List<Object> instanceData = new ArrayList<>();
        countIndexBottomAvg.forEach(map1 -> {
            instanceCategories.add(map1.get("title"));
            instanceData.add(map1.get("time"));
        });
        Map<String,Object> instanceSeries = new HashMap<>();
        instanceSeries.put("name","时长");
        instanceSeries.put("data",instanceData);
        List<Object> instanceSeriesList = new ArrayList<>();
        instanceSeriesList.add(instanceSeries);
        Map<String,Object> instanceSCountMap = new HashMap<>();
        instanceSCountMap.put("categories",instanceCategories);
        instanceSCountMap.put("series",instanceSeriesList);
        return ResultUtil.data(instanceSCountMap);
    }
    public Result<Object> countIndexBottomTimeOrder(ParamVo param ){
        getDateTime(param);
        List<Map<String, Object>>  countIndexBottomAvg;
        if(StringUtils.isBlank(param.getDepartId())){

            countIndexBottomAvg= indexMapper.countIndexBottomTimeOrder(param.getBeginDate(),param.getEndDate());
        }else {
            countIndexBottomAvg= indexMapper.countIndexBottomTimeOrderOnUser(param.getBeginDate(),param.getEndDate(),param.getDepartId());

        }
        List<Object> instanceCategories = new ArrayList<>();
        List<Object> instanceData = new ArrayList<>();
        countIndexBottomAvg.forEach(map1 -> {
            instanceCategories.add(map1.get("title"));
            instanceData.add(map1.get("count"));
        });
        Map<String,Object> instanceSeries = new HashMap<>();
        instanceSeries.put("name","超时次数");
        instanceSeries.put("data",instanceData);
        List<Object> instanceSeriesList = new ArrayList<>();
        instanceSeriesList.add(instanceSeries);
        Map<String,Object> instanceSCountMap = new HashMap<>();
        instanceSCountMap.put("categories",instanceCategories);
        instanceSCountMap.put("series",instanceSeriesList);
        return ResultUtil.data(instanceSCountMap);
    }
    public Result<Object> countIndexBottomTime(ParamVo param ){

        Map<String,Object> map=new HashMap<>();
        getDateTime(param);
        List<Map<String, Object>>  countIndexBottomTime= indexMapper.countIndexBottomTime(param.getBeginDate(),param.getEndDate(),param.getFirstRow(),param.getLastRow(),param.getDepartId());
        map.put("data",countIndexBottomTime);
        map.put("total",countIndexBottomTime.size());
        map.put("pageNumber",param.getPageNumber());
        return ResultUtil.data(map);
    }
}
